#include "widgettable.h"
#include "ui_widgettable.h"
#include <QLinkedList>
#include <QStringList>
#include "commondef.h"
#include <QMenu>

WidgetTable::WidgetTable(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::WidgetTable)
{
    ui->setupUi(this);
    
    initTableView();
    initTestHash();

    initCusModelTableView();

    initTableWidget();
}

WidgetTable::~WidgetTable()
{
    SAFE_FREE(m_actDevRefresh);
    SAFE_FREE(m_actMenu);

    delete ui;
}

/*************************
 * QTableView-初始化
 * ***********************/
void WidgetTable::initTableView()
{
    //自定义表头操作
    m_pTableHeader = new TableViewHeader(Qt::Horizontal, this);//表头
    m_pTableHeader->setStretchLastSection(true);//表头最后一列填充
    ui->tableView->setHorizontalHeader(m_pTableHeader);//设置表头

    //创建model（目前使用的是标准数据模型，可以自定义数据模型），绑定model
    m_pTableModel = new QStandardItemModel(this);
    ui->tableView->setModel(m_pTableModel);//设置model

    //右键菜单创建
    m_actMenu = new QMenu(ui->tableView);
    m_actMenu->setStyleSheet("border:1px solid #4d738b;");
    m_actDevRefresh = new QAction("Refresh", ui->tableView);
    connect(m_actDevRefresh, &QAction::triggered, [this]()
    {
        MY_DEBUG << "Refresh";
    });
    m_actMenu->addAction(m_actDevRefresh);


    //创建表头信息
    QStringList headerList;
    headerList << "" << tr("No.") << tr("Name") << tr("Sex") << tr("Age") << tr("ID");
    m_pTableModel->setHorizontalHeaderLabels(headerList);

    //单击
    connect(ui->tableView, &QTableView::clicked,
            this, &WidgetTable::on_tableViewClick);
    //双击
    connect(ui->tableView, &QTableView::doubleClicked,
            this, &WidgetTable::on_tableViewDbClick);

    //右键菜单设置
    ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->tableView, &QTableView::customContextMenuRequested,
            this, &WidgetTable::on_tableViewMenu);

    //标题头排序
    connect(ui->tableView->horizontalHeader(), &QHeaderView::sectionClicked,
            this, &WidgetTable::on_tableViewSort);
    //全选
    connect(m_pTableHeader, &TableViewHeader::stateChanged,
            this, &WidgetTable::on_tableViewSelectAllCheckBoxClick);

    //设置列宽
    setColumnWidth();

}

/*************************
 * QTableView-设置列宽
 * ***********************/
void WidgetTable::setColumnWidth()
{
    ui->tableView->setColumnWidth(COLUMN_NO, 100);
    ui->tableView->setColumnWidth(COLUMN_NAME, 200);
    ui->tableView->setColumnWidth(COLUMN_SEX, 100);
    ui->tableView->setColumnWidth(COLUMN_AGE, 100);
    //ui->tableView->setColumnWidth(COLUMN_ID, qRound(0.3*width));
}

void WidgetTable::resizeEvent(QResizeEvent *)
{
    setColumnWidth();
}

/*************************
 * QTableView-单击事件
 * ***********************/
void WidgetTable::on_tableViewClick(QModelIndex nIndex)
{
    QMutexLocker guard(&m_lock);

    int nRow = nIndex.row();
    int nCol = nIndex.column();

    Qt::CheckState oldState = m_pTableModel->item(nRow, COLUMN_CHECKBOX)->checkState();
    Qt::CheckState newState;

    if(oldState == Qt::Unchecked)
    {
        newState = Qt::Checked;
        m_nCheckedCount++;
    }
    else
    {
        newState = Qt::Unchecked;
        m_nCheckedCount--;
    }
    m_pTableModel->item(nRow, COLUMN_CHECKBOX)->setCheckState(newState);

    if(newState == Qt::Unchecked || m_nCheckedCount == m_pTableModel->rowCount())
    {
        m_pTableHeader->onStateChanged(newState);//改变标题栏的全选状态
    }
}

/*************************
 * QTableView-双击事件
 * ***********************/
void WidgetTable::on_tableViewDbClick(QModelIndex nIndex)
{
    QMutexLocker guard(&m_lock);

    int row = nIndex.row();

    MY_DEBUG << "Db Click row:" << row;
}

/*************************
 * QTableView-右键菜单显示
 * ***********************/
void WidgetTable::on_tableViewMenu(const QPoint &pos)
{
    //m_actMenu->exec(mapToGlobal(pos));//绝对位置
    m_actMenu->exec(cursor().pos());//相对位置
}

/*************************
 * QTableView-排序
 * ***********************/
void WidgetTable::on_tableViewSort(int nColumn)
{
    QMutexLocker guard(&m_lock);

    //点击表头实现排序
    ui->tableView->horizontalHeader()->setSortIndicatorShown(true);
    ui->tableView->sortByColumn(nColumn);
}

/*************************
 * QTableView-响应表头全选操作
 * ***********************/
void WidgetTable::on_tableViewSelectAllCheckBoxClick(Qt::CheckState state)
{
    QMutexLocker guard(&m_lock);
    int nRowCount = m_pTableModel->rowCount();//当前行数

    for(int i = 0; i < nRowCount; i++)
    {
        m_pTableModel->item(i, COLUMN_CHECKBOX)->setCheckState(state);
    }
}

/*************************
 * QTableView-更新数据
 * ***********************/
void WidgetTable::on_Btn_Update_clicked()
{
    QMutexLocker guard(&m_lock);

    //清空数据
    if(m_pTableModel->rowCount() > 0)
    {
        m_pTableModel->removeRows(0, m_pTableModel->rowCount());
    }

    QHashTestTableIterator i = m_testTableHash.begin();
    int row = 0;
    for(; i != m_testTableHash.end(); ++i)
    {
        TEST_TABLE_DATA data = i.value();

        //可以通过insertRow和setData增加数据
        m_pTableModel->insertRow(row, QModelIndex());
        m_pTableModel->setData(m_pTableModel->index(row, COLUMN_CHECKBOX), "");
        m_pTableModel->setData(m_pTableModel->index(row, COLUMN_NO), row+1);
        m_pTableModel->setData(m_pTableModel->index(row, COLUMN_NAME), data.sName);
        m_pTableModel->setData(m_pTableModel->index(row, COLUMN_SEX), data.nSex);
        m_pTableModel->setData(m_pTableModel->index(row, COLUMN_AGE), data.nAge);
        m_pTableModel->setData(m_pTableModel->index(row, COLUMN_ID), data.sID);

        //也可以通过setItem增加数据
        //m_pTableModel->setItem(row, COLUMN_CHECKBOX, new QStandardItem(""));

        // 设置全部列居中显示
        for(int j = COLUMN_NO; j <= COLUMN_ID; j++)
        {
            m_pTableModel->item(row, j)->setTextAlignment(Qt::AlignCenter);
        }
        row++;
    }
}

/*************************
 * QTableWidget-初始化
 * ***********************/
void WidgetTable::initTableWidget()
{
    //设置禁止修改
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //双击或获取焦点后单击，进入编辑状态
    //ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);

    //设置列数和列宽
    ui->tableWidget->setColumnCount(5);
    ui->tableWidget->setColumnWidth(0, 100);
    ui->tableWidget->setColumnWidth(1, 100);
    ui->tableWidget->setColumnWidth(2, 200);
    ui->tableWidget->setColumnWidth(3, 100);

    //设置列伸缩
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);

    //设置最后一栏自适应长度
    //ui->tableWidget->horizontalHeader()->setStretchLastSection(true);

    // 表格宽度随内容自动扩展
    //ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

    //设置连续选择状态
    ui->tableWidget->setSelectionMode(QAbstractItemView::ContiguousSelection);
    //设置为可以选中多个目标,按ctrl键
    //ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

    //开启交替行背景色,在设置style为交替颜色时必须开启
    //ui->tableWidget->setAlternatingRowColors(true);

    //不显示边框
    ui->tableWidget->setGridStyle(Qt::NoPen);
    connect(ui->tableWidget,SIGNAL(itemChanged(QTableWidgetItem*)),
            ui->tableWidget,SLOT(resizeRowsToContents()) );//自动换行

}

/*************************
 * QTableWidget-插入数据
 * ***********************/
void WidgetTable::on_Btn_Get_clicked()
{
    //设置表头
    QStringList headList;
    headList<<"NO."<<"Name"<<"Sex"<<"Age"<<"ID";
    ui->tableWidget->setColumnCount(headList.size());
    ui->tableWidget->setHorizontalHeaderLabels(headList); //设置水平表头为list

    //各列数据
    QStringList nameList;
    nameList << "AAA" << "BBB" << "CCC";
    QStringList sexList;
    sexList << "man" << "woman" << "woman";
    QStringList ageList;
    ageList << "32" << "30" << "3";
    QStringList idList;
    idList << "A11111" << "B11111" << "C111111";

    int num = ageList.size();
    for(int i = 0; i < num; i ++)
    {
        int Col = 0;
        //通过insertRow 和 setItem 插入数据
        int RowCont = ui->tableWidget->rowCount();
        ui->tableWidget->insertRow(RowCont);
        ui->tableWidget->setItem(RowCont, Col++, new QTableWidgetItem(QString::number(RowCont+1)));
        ui->tableWidget->setItem(RowCont, Col++, new QTableWidgetItem(nameList.at(i)));
        ui->tableWidget->setItem(RowCont, Col++, new QTableWidgetItem(sexList.at(i)));
        ui->tableWidget->setItem(RowCont, Col++, new QTableWidgetItem(ageList.at(i)));
        ui->tableWidget->setItem(RowCont, Col++, new QTableWidgetItem(idList.at(i)));

        //ui->tableWidget->setCellWidget()//可以放入组件例如QComboBox

        //设置各列数据居中显示
        for(int j = 0; j < Col; j++)
        {
            ui->tableWidget->item(RowCont, j)->setTextAlignment(Qt::AlignCenter);
        }
    }
    ui->tableWidget->scrollToBottom();
}


/*************************
 * QTableWidget-清除数据
 * ***********************/
void WidgetTable::on_Btn_Clear_clicked()
{
    QMutex mutex;
    QMutexLocker locker(&mutex);

    int RowCont = ui->tableWidget->rowCount();
    for(int i = RowCont; i >= 0; i--)
    {
        ui->tableWidget->removeRow(i);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////

/*************************
 * QTableView-自定义model
 * ***********************/
void WidgetTable::initCusModelTableView()
{
    m_pModelEx = new TableModel();
    ui->tableView_2->setModel(m_pModelEx);

    /*
    int nID = 0;
    //保存和恢复model选中项，因为在resetModel后会失效

    connect(m_pModelEx, &TableModel::modelAboutToBeReset, this, [=]{
      QModelIndex selectedIndex = ui->tableView_2->currentIndex();
      selectedIndex.data(Qt::UserRole).toInt();
    },Qt::DirectConnection);
    connect(m_pModelEx, &TableModel::modelReset, this, [=]{
        //不用担心无效的index，接口内部会处理
        //ui->tableView_2->setCurrentIndex(selectedIndex);
    },Qt::DirectConnection);
    */
}




///////////////////////////////////////////////////////////////////////////////////////////////

/*************************
 * 数据初始化
 * ***********************/
void WidgetTable::initTestHash()
{
    TEST_TABLE_DATA data[5];
    data[0] = {1, "AAA", 1, 31, "A1111111"};
    data[1] = {2, "BBB", 0, 33, "B1111111"};
    data[2] = {3, "CCC", 1, 29, "C1111111"};
    data[3] = {4, "DDD", 0, 26, "D1111111"};
    data[4] = {5, "EEE", 1, 32, "E1111111"};

    for(int i = 0; i < 5; i++)
    {
        m_testTableHash.insert(data[i].sID, data[i]);
    }
}

void WidgetTable::on_Btn_Update2_clicked()
{
    QVariantMap data_map;
    //标题
    data_map["headerlabel"] = QStringList() << "ID" << tr("jiange") << tr("device") << tr("device type") << tr("factory name") << tr("voltage type") << tr("wf identifier") << tr("wf tuichu");
    //数据
    for(int i = 0; i < 10000; i++)
    {
        QVariantMap map;
        map["ID"] = i + 1;
        map["jiange"] = i + 2;
        map["device"] = i + 3;
        map["device type"] = i + 4;
        map["factory name"] = i + 5;
        map["voltage type"] = i + 6;
        map["wf identifier"] = i + 7;
        map["wf tuichu"] = i + 8;
        data_map[QString::number(i) + "id"] = map;
    }
    m_pModelEx->SetData(data_map);
}


void WidgetTable::on_Btn_SetCurrentIndex_clicked()
{
    MY_DEBUG << "on_Btn_SetCurrentIndex_clicked";
    QVector< QPair<int, int> > indexs;
    for(int i = 0; i < 2000; i++)
    {
        indexs.append(qMakePair<int ,int>(i, 2));
    }
    m_pModelEx->setHignlightIndex(indexs);

}

void WidgetTable::on_Btn_SetColor_clicked()
{
    MY_DEBUG << "on_Btn_SetColor_clicked";

    m_pModelEx->setItemText(1, 1, "test");
    m_pModelEx->SetItemData(1, 1, "aoligei");
}


void WidgetTable::changeEvent(QEvent *event)
{
    switch(event->type())
    {
        case QEvent::LanguageChange:
            retranslateUi();
            break;
        default:
            QWidget::changeEvent(event);
    }
}

void WidgetTable::retranslateUi()
{
    ui->label->setText(tr("Use Table View:"));
    ui->label_2->setText(tr("Use Table Widget:"));
    ui->label_3->setText(tr("Use Table View(Custom Model)"));
    ui->Btn_Get->setText(tr("Get"));
    ui->Btn_Clear->setText(tr("Clear"));
    ui->Btn_Update->setText(tr("Update"));
    ui->Btn_Update2->setText(tr("Update"));
}
